package com.blqy.fr.user.service.impl;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.blqy.fr.common.constant.RedisConstant;
import com.blqy.fr.common.execption.BlQyException;
import com.blqy.fr.common.result.Result;
import com.blqy.fr.common.result.ResultCodeEnum;
import com.blqy.fr.model.user.*;

import com.blqy.fr.user.mapper.UserMapper;
import com.blqy.fr.user.service.UserService;
import com.blqy.fr.vo.user.UserDetailVo;
import com.blqy.fr.vo.user.UserMyVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    /*@Autowired
    private LoginClient loginClient;

    @Autowired
    private UserPaidAlbumMapper userPaidAlbumMapper;

    @Autowired
    private UserPaidTrackMapper userPaidTrackMapper;*/

    @Autowired
    private UserMapper userInfoMapper;

    // 微信码服务
    @Autowired
    private WxMaService wxMaService;

    // 远程调用账号，进行账号初始化
//    @Autowired
//    private UserAccountFeignClient userAccountFeignClient;
//
    @Autowired
    private RedisTemplate redisTemplate;
//
//    @Autowired
//    private UserPaidAlbumMapper userPaidAlbumMapper;
//
//    @Autowired
//    private UserPaidTrackMapper userPaidTrackMapper;
//    @Autowired
//    private UserSubscribeMapper userSubscribeMapper;

//    @Override
//    public Page<UserSubscribe> findUserSubscribePage(Integer page, Integer limit) {
//        Long userId = AuthContextHolder.getUserId();
//        Page<UserSubscribe> UserSubscribePage = userSubscribeMapper.findUserSubscribePage(new Page<>(page, limit), userId);
//        return UserSubscribePage;
//    }
//
//    @Transactional
//    @Override
//    public void updateVipExpireStat() {
//        UserInfo userInfo = new UserInfo();
//        userInfo.setIsVip(0);
//        /**
//         * 第一个参数，更新对象
//         * 第二个参数，查询条件
//         */
//        this.update(userInfo, new LambdaQueryWrapper<UserInfo>()
//                .eq(UserInfo::getIsVip, 1)
//                .lt(UserInfo::getVipExpireTime, LocalDateTime.now()));
//    }
//
//    @Override
//    public List<Long> getPaidTracksIdByAlbum(Long albumId) {
//        Long userId = AuthContextHolder.getUserId();
//        if (userId == null) {
//            return null;
//        }
//
//        List<UserPaidTrack> userPaidTracks = this.userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>()
//                .eq(UserPaidTrack::getAlbumId, albumId)
//                .eq(UserPaidTrack::getUserId, userId));
//
//        List<Long> list = userPaidTracks.stream().map(UserPaidTrack::getTrackId).toList();
//
//        return list;
//    }
//
//    @Override
//    public Boolean isPaidAlbum(Long albumId) {
//        Long userId = AuthContextHolder.getUserId();
//        return userPaidAlbumMapper.exists(new LambdaQueryWrapper<UserPaidAlbum>()
//                .eq(UserPaidAlbum::getAlbumId, albumId)
//                .eq(UserPaidAlbum::getUserId, userId));
//    }

    @Transactional
    @Override
    public Map<String, Object> wxLogin(String code) throws Exception {
        //1.根据code,appid和appsecret调用微信接口  获取openId
        WxMaJscode2SessionResult sessionInfo = wxMaService.getUserService().getSessionInfo(code);
        String openid = sessionInfo.getOpenid();
        // 2.如果获取openid失败，重新回调登陆页面
        //StringUtils.isEmpty(str)是否“无内容”（null 或 ""）
        if (StringUtils.isBlank(openid)/*是否“无意义内容”（null、空、全空白）*/) {
            throw new BlQyException(ResultCodeEnum.LOGIN_AUTH);
        }
        // 3.根据openId到user_info数据库表中获取用户信息userinfo
        User user = userInfoMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getWxOpenId, openid));
        //4.如果用户信息userinfo为空，说明还没注册,进行隐式注册
        if (user == null) {
            // 隐式注册
            user = new User();
            user.setWxOpenId(openid);
            // 在RedisConstrant中配置一个USER_NICKNAME_KEY = "user:nickname";
            //从10001,顺序递增,UUID不行,随机,太长,不是递增。redis定义一个key-value,value的初始值10000
            /**
             * redisTemplate.opsForValue()获取操作 RedisString 类型数据的工具
             * .set(key, value)存储一个键值对
             * .get(key)获取值
             * .increment(key)数值自增（+1）
             * .decrement(key)数值自减（-1）
             * .setIfAbsent(key, value)如果 key 不存在才设置（类似 SETNX）
             * .set(key, value, timeout, unit)设置值并带过期时间
             */
            user.setNickName("听友" + redisTemplate.opsForValue().increment(RedisConstant.USER_NICKNAME_KEY));
            user.setAvatar("https://img1.baidu.com/it/u=958010751,3701981661&fm=253&app=120&size=w931&n=0&f=JPEG&fmt=auto?sec=1739379600&t=150e5182e762861c6b6f16a0006dbd83");
            user.setStatus(1);
            userInfoMapper.insert(user);
            // TODO: 初始化账户信息
            //userAccountFeignClient.init(user.getId());//RPC远程调用
            //int i = 1/0;
        }
        //5.生成令牌，将令牌为key主要配分，以userinfo为value，保存到redis中
        String token = UUID.randomUUID().toString();
        //UserInfoVo userInfoVo = new UserInfoVo();
        //BeanUtils.copyProperties(userInfo, userInfoVo);
        //redisTemplate.opsForValue().set(RedisConstant.USER_LOGIN_KEY_PREFIX + token, userInfoVo, RedisConstant.USER_LOGIN_KEY_TIMEOUT, TimeUnit.SECONDS);
        //6.返回令牌给客户端(只返回令牌，不返回用户信息)
        Map<String, Object> map = new HashMap<>();
        map.put("token", token);
        return map;
    }

    /*//@GlobalTransactional
    @Transactional
    @Override
    public Map<String, String> login(String code) throws WxErrorException {
        LoginVo loginVo = new LoginVo();
        loginVo.setCode(code);
        return this.loginClient.login(LoginType.WX_LOGIN, loginVo);
    }

    @Override
    public Boolean isPaidAlbum(Long albumId) {
        Long userId = AuthContextHolder.getUserId();
        return this.userPaidAlbumMapper.selectCount(new LambdaQueryWrapper<UserPaidAlbum>()
                .eq(UserPaidAlbum::getAlbumId, albumId).eq(UserPaidAlbum::getUserId, userId)) > 0;
    }

    @Override
    public List<UserPaidTrack> getPaidTracks(Long albumId) {
        Long userId = AuthContextHolder.getUserId();
        return this.userPaidTrackMapper.selectList(new LambdaQueryWrapper<UserPaidTrack>()
                .eq(UserPaidTrack::getAlbumId, albumId).eq(UserPaidTrack::getUserId, userId));
    }

    @Override
    public void updateExpiredVipStatus() {
        UserInfo userInfo = new UserInfo();
        userInfo.setIsVip(0);
        // 今天凌晨时间
        LocalDateTime localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);
        Date date = Date.from(localDateTime.toInstant(ZoneOffset.UTC));
        // 如果vip的过期时间小于今天凌晨，说明vip的过期时间是今天以前
        this.update(userInfo, new LambdaUpdateWrapper<UserInfo>().eq(UserInfo::getIsVip, 1).le(UserInfo::getVipExpireTime, date));
    }*/

    @Override
    public UserMyVo findUserTwo(Long userId, Long roleId) {
        return userInfoMapper.findUserTwo(userId, roleId);
    }

    @Override
    public UserDetailVo findUserThree(Long id) {
        return userInfoMapper.findUserThree(id);
    }

    @Override
    public void updateUserInfo(UserDetailVo userDetailVo) {
        // 1. 检查用户是否存在且未删除
        User user = baseMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getId, userDetailVo.getId())
                .eq(User::getIsDeleted, 0)
        );
        if (user == null) {
            throw new RuntimeException("用户不存在或已删除");
        }

        // 2. 检查用户名是否被他人占用（可选）
        boolean exists = baseMapper.exists(new LambdaQueryWrapper<User>()
                .eq(User::getUserName, userDetailVo.getUserName())
                .ne(User::getId, userDetailVo.getId()) // 排除自己
                .eq(User::getIsDeleted, 0)
        );
        if (exists) {
            throw new RuntimeException("用户名已被占用");
        }

        // 3. 更新允许的字段
        user.setNickName(userDetailVo.getNickName());
        user.setAvatar(userDetailVo.getAvatar());
        user.setBirth(userDetailVo.getBirth());
        user.setGender(userDetailVo.getGender());
        //头像、昵称、性别、生日
        // 注意：不要 setUpdateTime！MyBatis-Plus 会自动更新

        // 4. 执行更新
        userInfoMapper.updateById(user);
    }
}
